package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class) // 事务：出现异常回滚
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    private AlbumAttributeValueMapper albumAttributeValueMapper;
    private AlbumStatMapper albumStatMapper;
    private AlbumInfoMapper albumInfoMapper;
    private RabbitTemplate rabbitTemplate;
    private RBloomFilter initBloomFilter;

    /**
     * 保存专辑信息
     *
     * @param albumInfoVo 专辑信息
     */
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        // 声明DO
        AlbumInfo albumInfo = new AlbumInfo();
        // 将VO数据拷贝到DO
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        // TODO-补全部分数据:默认值
        albumInfo.setUserId(1L);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_WAIT);
        // 新增专辑数据
        if (!save(albumInfo)) {
            throw new GuiguException(201, "新增专辑数据失败!");
        }
        // 获取专辑的id
        Long albumId = albumInfo.getId();
        // 保存专辑的标签数据
        saveAlbumAttributeValueVo(albumId, albumInfoVo.getAlbumAttributeValueVoList());
        // 初始化专辑的统计数据
        initAlbumStat(albumId);

        // 判断专辑是否公开 公开1 私有0
        String isOpen = albumInfoVo.getIsOpen();
        if (isOpen.equals("1")) {
            // 将专辑的数据写入es中
            rabbitTemplate.convertAndSend("album_and_search_exchange", "album.upper", albumId + "");
        }
        // 布隆过滤器添加专辑数据
        initBloomFilter.add("getAlbumInfo:" + Arrays.asList(albumInfo.getId()).toString());
    }

    /**
     * 分页查询专辑的数据
     *
     * @param page           分页参数
     * @param albumInfoQuery 查询条件
     * @return 专辑数据
     */
    @Override
    public Page<AlbumListVo> findAlbumInfoPage(Page<AlbumListVo> page, AlbumInfoQuery albumInfoQuery) {
        return albumInfoMapper.selectPageAlbumInfo(albumInfoQuery, page);
    }

    /**
     * 删除专辑 ：逻辑删除
     *
     * @param albumId 专辑id
     */
    @Override
    public void removeAlbumInfo(Long albumId) {
        // 删除专辑表数据: 和用户绑定!
        int delete = albumInfoMapper.delete(
                new LambdaQueryWrapper<AlbumInfo>()
                        .eq(AlbumInfo::getUserId, 1L)
                        .eq(AlbumInfo::getId, albumId));
        if (delete <= 0) {
            throw new GuiguException(201, "专辑不存在!");
        }
        // 标签数据:删除
        albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId, albumId));
        // 统计数据:删除
        albumStatMapper.delete(
                new LambdaQueryWrapper<AlbumStat>()
                        .eq(AlbumStat::getAlbumId, albumId));
        // 删除es中专辑数据
        rabbitTemplate.convertAndSend("album_and_search_exchange", "album.down", albumId + "");

        //删除redis中专辑数据
        rabbitTemplate.convertAndSend("album_and_search_exchange", "album.redis", albumId + "");
    }

    /**
     * 修改-回显专辑信息
     *
     * @param albumId 专辑id
     * @return 专辑信息
     */
    @Override
    public Object getAlbumInfo(Long albumId) {
        // 查询当前用户的专辑信息
        AlbumInfo albumInfo = getOne(new LambdaQueryWrapper<AlbumInfo>()
                .eq(AlbumInfo::getUserId, 1L)
                .eq(AlbumInfo::getId, albumId));

        // 判断信息是否存在
        if (albumInfo == null) {
            throw new GuiguException(201, "专辑不存在!");
        }

        // 查询当前用户的专辑标签数据
        List<AlbumAttributeValue> albumAttributeValueList =
                albumAttributeValueMapper.selectList(
                        new LambdaQueryWrapper<AlbumAttributeValue>()
                                .eq(AlbumAttributeValue::getAlbumId, albumId));
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);

        // 返回
        return albumInfo;
    }

    /**
     * 修改专辑 - 提交更新
     *
     * @param albumId     专辑id
     * @param albumInfoVo 专辑信息
     */
    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 查询当前用户的专辑信息
        AlbumInfo albumInfo = getOne(new LambdaQueryWrapper<AlbumInfo>()
                .eq(AlbumInfo::getUserId, 1L)
                .eq(AlbumInfo::getId, albumId));
        // 判断信息是否存在
        if (albumInfo == null) {
            throw new GuiguException(201, "专辑不存在!");
        }
        // 属性转移
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        // 修改专辑的数据
        updateById(albumInfo);
        // 标签表 删除旧数据
        albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId, albumId));
        // 标签表 保存新数据
        saveAlbumAttributeValueVo(albumId, albumInfoVo.getAlbumAttributeValueVoList());

        // 判断专辑是否公开 公开1 私有0
        String isOpen = albumInfoVo.getIsOpen();
        if (isOpen.equals("1")) {
            //  公开 将专辑的数据写入es中
            rabbitTemplate.convertAndSend("album_and_search_exchange", "album.upper", albumId + "");
        } else {
            // 私有 删除es中专辑数据
            rabbitTemplate.convertAndSend("album_and_search_exchange", "album.down", albumId + "");

            //删除redis中专辑数据
            rabbitTemplate.convertAndSend("album_and_search_exchange", "album.redis", albumId + "");
        }
    }

    /**
     * 保存专辑标签数据
     *
     * @param albumId                   专辑id
     * @param albumAttributeValueVoList 专辑标签数据
     */
    private void saveAlbumAttributeValueVo(Long albumId, List<AlbumAttributeValueVo> albumAttributeValueVoList) {
        // 循环新增
        albumAttributeValueVoList.stream().forEach(albumAttributeValueVo -> {
            // 声明DO
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            // 拷贝属性
            BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
            // 补全专辑id
            albumAttributeValue.setAlbumId(albumId);
            // 新增
            int insert = albumAttributeValueMapper.insert(albumAttributeValue);
            if (insert <= 0) {
                throw new GuiguException(201, "新增专辑的标签数据失败");
            }
        });
    }

    /**
     * 创作音频-查询用户专辑列表
     *
     * @return 查询结果
     */
    @Override
    public Object findUserAllAlbumList() {
        // 查询专辑列表：当前用户、审核通过、未完结的
        return page(new Page<>(1, 10), new LambdaQueryWrapper<AlbumInfo>()
                .eq(AlbumInfo::getUserId, 1L)
                .eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
                .eq(AlbumInfo::getIsFinished, 0)
                // 降序
                .orderByDesc(AlbumInfo::getId))
                // 获取list
                .getRecords();
    }

    /**
     * 查询专辑的标签列表
     *
     * @param albumId 专辑id
     * @return 专辑的标签列表
     */
    @Override
    public List<AlbumAttributeValue> getAlbumAttributeValueList(Long albumId) {
        return albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, albumId));
    }

    /**
     * 查询专辑的统计信息
     *
     * @param albumId 专辑id
     * @return 专辑的统计信息
     */
    @Override
    public Map<String, Object> getAlbumStatMap(Long albumId) {
        // 查询统计数据
        List<AlbumStat> albumStatList = albumStatMapper.selectList(new LambdaQueryWrapper<AlbumStat>()
                .eq(AlbumStat::getAlbumId, albumId));
        return albumStatList.stream().collect(Collectors.toMap(
                albumStat -> albumStat.getStatType(),
                albumStat -> albumStat.getStatNum()));
    }

    /**
     * 初始化统计数据
     *
     * @param albumId 专辑id
     */
    private void initAlbumStat(Long albumId) {
        // 声明DO-播放量初始化
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatNum(0);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_PLAY);
        albumStatMapper.insert(albumStat);
        // 声明DO-订阅量初始化
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        albumStatMapper.insert(albumStat);
        // 声明DO-购买量初始化
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_BROWSE);
        albumStatMapper.insert(albumStat);
        // 声明DO-评论量初始化
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_COMMENT);
        albumStatMapper.insert(albumStat);
    }
}
